home *** CD-ROM | disk | FTP | other *** search
- 'A tutorial for Richard Backus' BASICDOS.BAS code. Here is
- 'the code in the original form that he sent to me:
-
- '===========>8 CLIP 8<============
-
- ' BASICDOS.BAS
- ' written: Richard J Backus 27dec95
- ' purpose: to provide a BASIC BIOS/DOS call interface
- ' method: using the CALL interface, get registers, call the interrupt, and
- ' return the registers. Based on QuickBasic's CALL INTERRUPT routine.
- ' Warning: Calls requiring segment registers cannot be used.
-
- ' QBasic syntax: CALL ABSOLUTE(intnum%, callregs, retregs, VARPTR(asmcode)))
- ' intnum% a valid DOS interrupt number between 0 and 255, type INTEGER
- ' callregs register values required by call, type REGS
- ' retregs register values returned from call, type REGS
- TYPE REGS 'Typedef for DOS registers
- ax AS INTEGER
- bx AS INTEGER
- cx AS INTEGER
- dx AS INTEGER
- bp AS INTEGER
- si AS INTEGER
- di AS INTEGER
- flg AS INTEGER
- END TYPE
- ' DOS call code
- DATA &H55, &H06, &H1E, &H8B, &HEC, &H9C, &H8B, &H7E, &H0E, &H8A
- DATA &H05, &H8B, &H7E, &H0C, &HB4, &H35, &HCD, &H21, &H8B, &H46
- DATA &HF8, &H05, &H20, &H00, &H0E, &H50, &H06, &H53, &H8B, &H05
- DATA &H8B, &H5D, &H02, &H8B, &H4D, &H04, &H8B, &H55, &H06, &H8B
- DATA &H6D, &H08, &H8B, &H75, &H0A, &H8B, &H7D, &H0C, &HFA, &HCB
- DATA &H1F, &H07, &H57, &H9C, &H8B, &HFC, &H36, &H8B, &H7D, &H0A
- DATA &H89, &H05, &H89, &H5D, &H02, &H89, &H4D, &H04, &H89, &H55
- DATA &H06, &H89, &H6D, &H08, &H89, &H75, &H0A, &H58, &H89, &H45
- DATA &H0E, &H58, &H89, &H45, &H0C, &H5D, &HCA, &H06, &H00
- ' Load DOS/BIOS interface routine
- DIM dos%(45) 'get some memory space
- DEF SEG = VARSEG(dos%(0))
- FOR i% = 0 TO 88
- READ d%
- POKE VARPTR(dos%(0))+i%, d% 'copy code into memory
- NEXT i%
-
- ' Message string
- DATA &H48, &H65, &H6C, &H6C, &H6F, &H20, &H57, &H6F, &H72, &H6C
- DATA &H64, &H0D, &H0A
- ' use DOS to output the message
- DIM dosregs AS REGS
- FOR i% = 0 TO 12
- intnum% = &H21 'parameters for call
- dosregs.ax% = &H200
- READ dosregs.dx%
- DEF SEG = VARSEG(dos%(0)) 'set call seg
- CALL ABSOLUTE(intnum%, dosregs, dosregs, VARPTR(dos%(0)))
- NEXT i%
- END
-
- '=============>8 CLIP 8<================
-
- 'TYPE REGS will set up the variable REGS to access all the registers
- 'you need to make a BIOS call. This goes in hand with the DIM dosregs
- 'as REGS. Dosregs will contain the information of the registers. For
- 'example, if you want to send a value to the AX register, you can set
- 'dosregs.ax=value. I'm not great at explaining how TYPE works, so best
- 'consult some books (or the help file) on that one. :)
-
- 'Next he has his assembly routine that emulates CALL INTERRUPT. This
- 'and the code under it that pokes the routine into memory is the heart
- 'of the whole thing.
-
- 'Next, he creates the data for each character in the string "Hello
- 'World" and he uses a BIOS video call to place each character on the
- 'screen (much the same way my GPrint routine does in my GUI interface).
- '
- 'Note how he used CALL ABSOLUTE. Lets compare it with QB45's CALL
- 'INTERRUPT syntax:
-
- 'QB45: CALL INTERRUPT (intnum%, dosregs, dosregs)
- 'QBASIC: CALL ABSOLUTE (intnum%, dosregs, dosregs, VARPTR(dos%(0)))
-
- 'Notice all is basically the _same_, you just add the VARPTR at the
- 'end! And don't forget to change INTERRUPT to ABSOLUTE. This makes it
- 'very easy to change a QB45 code to work with QBasic.
-
- 'Now, I will try and explain how you can convert QB45 code that uses
- 'CALL INTERRUPT so that it will work in QBasic. Of course, you'll need
- 'the code written by Richard Backus (which was posted in the previous
- 'message). Also note this works only for the CALL INTERRUPT calls. If
- 'you see CALL INTERRUPTX or CALL INT86, I'm not sure how it will work
- 'with those, as they take slightly different parameters.
-
- 'First off, the QB45 program will have a '$INCLUDE statement in it.
- 'You must delete that statement. Next, put the TYPE REGS in AFTER the
- 'DECLARE SUB and DECLARE FUNCTION statements (if any). You'll want to
- 'more than likely change REGS to RegType, as that is what the qb.bi was
- 'using. This will replace it.
-
- 'Now, put the DIM SHARED Inregs as RegType, Outregs as RegType with the
- 'DIM statements, if there isn't one there already. Most often than
- 'not, it may not need changing. Also add in DIM SHARED dos%(45) and
- 'DEF SEG = VARSEG(dos%(0)). It should look something like this:
-
- 'DIM and CONST, etc. here
- 'DIM SHARED Inregs as RegType, Outregs as RegType
- 'DIM SHARED dos%(45)
- 'DEF SEG = VARSEG(dos%(0))
-
- 'Once you have the variables all set up, next slip the DOS Call Code
- 'data statements and the Load DOS/BIOS interface routine just before
- 'the main code of the program starts. Most of the time, there's a CLS
- 'or SCREEN statement there.
-
- 'Now just one more step. Look through the code (may want to do a
- 'search for CALL INTERRUPT). You will need to change each occurrence of
- 'INTERRUPT to ABSOLUTE. And, you will need to add to the end of each
- 'CALL ABSOLUTE (which was a CALL INTERRUPT) the VARPTR statement. For
- 'example, suppose the QB45 code read:
-
- ' CALL INTERRUPT (intnum%, Inregs, Outregs)
-
- 'You would change it to read:
-
- ' CALL ABSOLUTE (intnum%, Inregs, Outregs, VARPTR(dos%(0)))
-
- 'Be sure to get all the parenthesis right! There's _3_ of them at the
- 'end of the ABSOLUTE statement (I say this because I'm bad at it and
- 'forget a lot! :)
-
- 'Now you can save the new code to a new file name (for safe keeping)
- 'and run it. It should work!
-
- 'If you have any questions, let me know. I can't promise I'll be able
- 'to have an answer every time but I'll try. If you need to contact
- 'Richard, net mail me and I'll forward your question or whatever to
- 'him. Just a short note that he does most of his programming in
- 'assembly. :)
-
-